

function get_gtk_ui_root(ui_data)
    if (ui_data:tag() ~= nil) and (ui_data:tag() == "interface") then
        return {ui_data, ui_data, 1, nil}
    end
    return nil
end

function get_gtk_ui_first_child(ui_data, node)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            local child_table = curr_node:find(nil)
            if child_table ~= nil and child_table[1] ~= nil then
                return {child_table[1], child_table, 1, node}
            end
        end
    end
    return nil
end

function get_gtk_ui_parent(ui_data, node)
    if node ~= nil then
        local parent_node = node[4]
        if parent_node ~= nil then
            return parent_node
        end
    end
    return nil
end

function get_gtk_ui_next_child(ui_data, node, child)
    if node ~= nil then
        local curr_node, parent_node, index = child[1], child[2], child[3]
        if curr_node ~= nil then
            if (parent_node[index + 1] ~= nil) then
                return {parent_node[index + 1], parent_node, index + 1, node}
            end
        end
    end
    return nil
end

function get_gtk_ui_has_child(ui_data, node, name)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            for k, v in curr_node:children(name) do
                return true
            end
        end
    end
    return false
end

function get_gtk_ui_get_child(ui_data, node, name)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            local child_list = {}
            -- 搜索所有子结点加入到一个临时列表中
            for k, v in curr_node:children(name) do
                table.insert(child_list, v)
            end
            -- 如果列表不为空，则返回第一个子结点
            if child_list[1] ~= nil then
                return {child_list[1], child_list, 1, node}
            end
        end
    end
    return nil
end

function get_gtk_ui_node_name(ui_data, node)
    if node ~= nil then
        if node[1] ~= nil then
            return node[1]:tag()
        end
    end
    return nil
end

function get_gtk_ui_node_value(ui_data, node)
    if node ~= nil then
        if node[1] ~= nil then
            return node[1][1]
        end
    end
    return nil
end

function get_gtk_ui_first_property(ui_data, node)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            for key_, val_ in pairs(curr_node) do
                if type(key_) == "string" then  
                    -- print(key_, val_)
                    return {curr_node, {key_, val_}, 1}
                end
            end
            return nil
        end
    end
    return nil
end

function get_gtk_ui_next_property(ui_data, node, attr)
    if attr ~= nil then
        local curr_node, attr_pair, index = attr[1], attr[2], attr[3]
        local next_index = index + 1
        for key_, val_ in pairs(curr_node) do
            if type(key_) == "string" then  
                if index == 0 then
                    -- print(key_, val_)
                    return {curr_node, {key_, val_}, next_index}
                end
                index = index - 1
            end
        end
    end
    return nil
end

function get_gtk_ui_has_property(ui_data, node, name)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            for key_, val_ in pairs(curr_node) do
                if (type(key_) == "string") then  
                    if (key_ == name) then
                        return true
                    end
                end
            end
            return false
        end
    end
    return false
end

function get_gtk_ui_get_property(ui_data, node, name)
    if node ~= nil then
        local curr_node, parent_node, index = node[1], node[2], node[3]
        if curr_node ~= nil then
            for key_, val_ in pairs(curr_node) do
                if type(key_) == "string" then  
                    if (key_ == name) then
                        return {curr_node, {key_, val_}, 1}
                    end
                end
            end
            return nil
        end
    end
    return nil
end

function get_gtk_ui_property_name(ui_data, node, attr)
    if attr ~= nil then
        if attr[2] ~= nil then
            return attr[2][1]
        end
    end
    return nil
end

function get_gtk_ui_property_value(ui_data, node, attr)
    if attr ~= nil then
        if attr[2] ~= nil then
            return attr[2][2]
        end
    end
    return nil
end

-- 获取当前脚本的路径
local curr_path = string.match(string.gsub(debug.getinfo(1,"S").short_src, "\\", "/"), "^.*/")
-- 将当前脚本当前目录加入package搜索列表中
package.path = string.format("%s?.lua;%s?/init.lua;%s", curr_path, curr_path, package.path)
print("package.path: " .. package.path)

-- 添加调试 
--require("socket.core")
--require("LuaPanda").start("127.0.0.1", 8818)
print("*****************************************************")

require("GenGtkCode")
--require("lfs")

-- 测试代码则以luaXML方式加载相应的UI文件
local xml = require("LuaXML")

-- 工作目标，主文件
local ui_file  = arg[1]
-- 模板文件
local template_file  = arg[2]
-- 目标文件夹，生成代码的位置
local dest_folder  = arg[3]

-- 主窗口名称，可为空
local main_widget = nil
-- 应用名称，可为空
local app_name = nil
-- 项目ID文件，可为空
local project_id_file = nil
--默认Gtk版本224
local gtk_version = "224";

-- 扫描剩余参数，并设置相关变量
for i = 4, #arg do
	local param = arg[i]
	if string.find(param, "^%-%-main%-widget=") then
		main_widget = string.sub(param, 15)
	elseif string.find(param, "^%-%-app%-name=") then
		app_name = string.sub(param, 12)
	elseif string.find(param, "^%-%-project%-id=") then
		project_id_file = string.sub(param, 14)
    elseif string.find(param, "^%-%-gtk%-ver=") then
        gtk_version = string.sub(param, 11)
	end
end

if not GtkUtils.check_file_exists(ui_file) then
	print("ui file not exist: " .. ui_file)
	return
end

if not GtkUtils.check_file_exists(template_file) then
	print("template file not exist: " .. template_file)
	return
end

if project_id_file and not GtkUtils.check_file_exists(project_id_file) then
	print("project_id_file file not exist: " .. project_id_file)
	return
end

if not GtkUtils.check_folder_exists(dest_folder) then
    print("dest folder not exist: " .. dest_folder)
    return
end

-- 装载XML文件
local ui_handle = xml.load(ui_file)
if ui_handle == nil then
    print("open ui file fail!" .. ui_file)
	return
end

-- 如果gtk_version=auto
if string.lower(gtk_version) == "auto" then
    -- 则根据XML文件中的类型，require libs version来确定gtk版本
    local get_gtk_version = get_gtk_version_from_xml(ui_handle, "224")
    if get_gtk_version ~= nil then
        gtk_version = get_gtk_version
    else
        print("[ERROR]unknown ui file!")
        return
    end
end

-- 后续应根据XML文件中的类型，来加载不同的基础类库
require("pango" .. gtk_version)
require("gdk" .. gtk_version)
require("gtk" .. gtk_version)

-- 将Gtk指向Gtk224版本
if _G["Gtk" .. gtk_version] ~= nil then
    if type(_G["Gtk" .. gtk_version]) == "table" then
        Gtk = _G["Gtk" .. gtk_version];
    else
        print("[ERROR] bad Gtk variable, type is " .. type(_G["Gtk"]) .. "!")
        return
    end
else
    print("[ERROR] unknown Gtk variable!")
    return
end

-- 写代码
gen_gtk_code(ui_handle, template_file, dest_folder, project_id_file, main_widget, app_name)
